package cn.mumzone.pos.ui.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;

import com.github.jdsjlzx.interfaces.OnLoadMoreListener;
import com.github.jdsjlzx.recyclerview.LRecyclerView;
import com.github.jdsjlzx.recyclerview.LRecyclerViewAdapter;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import cn.mumzone.basic.adapter.TextWatcherAdapter;
import cn.mumzone.basic.base.BaseActivity;
import cn.mumzone.basic.util.EditTextUtil;
import cn.mumzone.basic.util.ListUtil;
import cn.mumzone.basic.util.PosToast;
import cn.mumzone.basic.util.RxBus;
import cn.mumzone.basic.util.StringUtils;
import cn.mumzone.pos.AppConstants;
import cn.mumzone.pos.R;
import cn.mumzone.pos.event.InOrOutStockEvent;
import cn.mumzone.pos.model.RepoGoodsEntity;
import cn.mumzone.pos.model.RepoListGoodsEntity;
import cn.mumzone.pos.model.RepositoryEntity;
import cn.mumzone.pos.presenter.StockOutSearchPresenter;
import cn.mumzone.pos.presenter.contract.StockOutSearchContract;
import cn.mumzone.pos.ui.adapter.ADA_StockInAndOut;
import cn.mumzone.pos.ui.fragment.FRA_StockIn;
import cn.mumzone.pos.ui.fragment.FRA_StockOut;
import cn.mumzone.pos.ui.widgets.refresh.SmartRefreshLayout;
import cn.mumzone.pos.ui.widgets.refresh.api.RefreshLayout;
import cn.mumzone.pos.ui.widgets.refresh.listener.OnRefreshListener;
import retrofit2.http.POST;

/**
 * Created by JoeLjt on 2019/10/8.
 * Email: lijiateng1219@gmail.com
 * Description:
 * <p>
 * 出库手动搜索页面
 * 搜索后操作数量，在数量监听中将结果通过 RxBus 实时发送给 {@link cn.mumzone.pos.ui.fragment.FRA_StockOut}
 */
public class ACT_SearchStockInOrOut extends BaseActivity<StockOutSearchPresenter> implements StockOutSearchContract.View {

    public static final String KEY_SELECTED_REPO = "key_selected_repo";
    public static final String KEY_LOCAL_LIST = "key_local_list";

    public static final String KEY_STOCK_TYPE = "key_stock_type";
    public static final String KEY_OTHER_IN_TYPE = "key_other_in_type";

    public static final String KEY_SCAN_CODE = "key_scan_code";
    public static final String KEY_SCAN_LIST = "key_scan_list";

    @BindView(R.id.ll_search_title_bar)
    LinearLayout llSearchTitle;
    @BindView(R.id.iv_clear_input)
    ImageView ivClearInput;
    @BindView(R.id.et_search_goods)
    EditText etSearch;
    @BindView(R.id.rb_search)
    RadioButton rbSearch;

    @BindView(R.id.ll_empty_cart)
    LinearLayout llEmpty;
    @BindView(R.id.ll_goods)
    LinearLayout llGoods;
    @BindView(R.id.refresh_layout)
    SmartRefreshLayout refreshLayout;
    @BindView(R.id.rv_cart_goods)
    LRecyclerView rvCart;

    @BindView(R.id.tv_select_count)
    TextView tvSelectCount;
    @BindView(R.id.tv_confirm)
    TextView tvConfirm;

    private RepositoryEntity mSelectedRepo;

    private LRecyclerViewAdapter mGoodsViewAdapter;
    private ADA_StockInAndOut mStockAdapter;

    private boolean isFromScan;
    private String scanCode;
    private int stockType;
    private boolean isOtherStockIn;
    private List<RepoListGoodsEntity> scanResult;
    private List<RepoListGoodsEntity> localCartList;

    private List<RepoListGoodsEntity> mSelectedData;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        overridePendingTransition(R.anim.right_in, R.anim.right_out);
        super.onCreate(savedInstanceState);
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.gravity = Gravity.END;
        params.height = WindowManager.LayoutParams.MATCH_PARENT;
        getWindow().setAttributes(params);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

        setFinishOnTouchOutside(true);
    }

    @Override
    protected void getBundleExtras(Bundle extras) {
        mSelectedRepo = (RepositoryEntity) extras.getSerializable(KEY_SELECTED_REPO);
        localCartList = (List<RepoListGoodsEntity>) extras.getSerializable(KEY_LOCAL_LIST);
        scanCode = extras.getString(KEY_SCAN_CODE, null);
        scanResult = (List<RepoListGoodsEntity>) extras.getSerializable(KEY_SCAN_LIST);
        isFromScan = !TextUtils.isEmpty(scanCode);
        stockType = extras.getInt(KEY_STOCK_TYPE);
        isOtherStockIn = extras.getBoolean(KEY_OTHER_IN_TYPE);

    }

    @Override
    protected void initEventAndData() {

        initSearchCartRv();

        showSearchResultTitleBar();

        updateStockSearchResultUI(!isFromScan);

        if (isFromScan) {
            updateListAccordingToLocalCart(scanResult);
            mStockAdapter.update(scanResult, true);
        }

    }

    private void showSearchResultTitleBar() {
        llSearchTitle.setVisibility(isFromScan ? View.GONE : View.VISIBLE);
        tvConfirm.setText(stockType == FRA_StockIn.STOCK_TYPE_IN ? "加入入库" : "加入出库");
    }

    private void updateStockSearchResultUI(boolean showDefault) {
        llEmpty.setVisibility(showDefault ? View.VISIBLE : View.GONE);
        rvCart.setVisibility(!showDefault ? View.VISIBLE : View.GONE);
    }

    private void initSearchCartRv() {

        rvCart.setLayoutManager(new LinearLayoutManager(mContext));
        mStockAdapter = new ADA_StockInAndOut(this, stockType, false);
        mGoodsViewAdapter = new LRecyclerViewAdapter(mStockAdapter);
        mStockAdapter.setOnAmountChangeListener(new ADA_StockInAndOut.OnAmountChangeListener() {
            @Override
            public void onAmountChanged(int count, int tag, RepoListGoodsEntity entity) {

                // RxBus.getDefault().post(new InOrOutStockEvent(entity));

                // v2.3 取消搜索页与结果页实时交互，添加确认按钮
                tvSelectCount.setText(String.valueOf(mStockAdapter.getSelectedCount()));
                tvConfirm.setEnabled(mStockAdapter.getSelectedCount() > 0);

            }
        });

        rvCart.setAdapter(mGoodsViewAdapter);
        rvCart.setPullRefreshEnabled(false);
        rvCart.setLoadMoreEnabled(true);
        rvCart.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore() {
                String keyword = etSearch.getText().toString().trim();
                mPresenter.loadRepoGoodsById(mSelectedRepo != null ? StringUtils.get(mSelectedRepo.getId()) : "", "",
                        isFromScan ? scanCode : keyword, isFromScan, false, getSearchTypeAccordingToStockType());
            }
        });

        if (!isFromScan) {
            refreshLayout.setOnRefreshListener(new OnRefreshListener() {
                @Override
                public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                    updateStockSearchResultUI(false);
                    String keyword = etSearch.getText().toString();
                    mPresenter.loadRepoGoodsById(mSelectedRepo != null ? StringUtils.get(mSelectedRepo.getId()) : "", "",
                            keyword, isFromScan, true, getSearchTypeAccordingToStockType());
                    rvCart.setNoMore(false);
                }
            });

            etSearch.addTextChangedListener(new TextWatcherAdapter() {
                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    boolean isInputNotEmpty = !TextUtils.isEmpty(etSearch.getText().toString());
                    ivClearInput.setVisibility(isInputNotEmpty ? View.VISIBLE : View.GONE);
                    rbSearch.setEnabled(isInputNotEmpty);
                    rbSearch.setChecked(isInputNotEmpty);
                }
            });

            etSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                @Override
                public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                    if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                        EditTextUtil.hideSoftInput(mContext, v);

                        updateStockSearchResultUI(false);
                        refreshLayout.autoRefresh();
                    }
                    return false;
                }
            });

        } else {
            // 扫码添加数据时禁止刷新
            refreshLayout.setEnableRefresh(false);
        }

    }

    private String getSearchTypeAccordingToStockType() {
        if (stockType == FRA_StockIn.STOCK_TYPE_IN) {
            return isOtherStockIn ? "1" : "2";
        } else if (stockType == FRA_StockOut.STOCK_TYPE_OUT) {
            return "3";
        }
        return "0";
    }

    @Override
    protected int getLayout() {
        return R.layout.act_search_stock_out;
    }

    @Override
    protected View getTargetView() {
        return llGoods;
    }

    @OnClick({R.id.iv_finish, R.id.iv_clear_input, R.id.rb_search, R.id.tv_confirm})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_finish:
                finish();
                overridePendingTransition(R.anim.right_in, R.anim.right_out);
                break;
            case R.id.iv_clear_input:
                if (!TextUtils.isEmpty(etSearch.getText().toString())) {
                    toggleCloseEmpty();
                    etSearch.setText("");
                    mStockAdapter.clear();
                    updateStockSearchResultUI(true);
                }
                break;
            case R.id.rb_search:
                refreshLayout.autoRefresh();
                break;
            case R.id.tv_confirm:
                mSelectedData = mStockAdapter.getSelectedData();
                RxBus.getDefault().post(new InOrOutStockEvent(mStockAdapter.getDataList()));

                etSearch.setText("");
                mStockAdapter.clear();
                tvSelectCount.setText("0");
                tvConfirm.setEnabled(false);
                updateStockSearchResultUI(true);
                PosToast.INSTANCE.makeCheckMarkToast(mContext, String.format("已%s~", tvConfirm.getText().toString()));
                break;
        }
    }

    public static void startActFromStockOut(Activity activity, RepositoryEntity selectedRepo, LinkedList<RepoListGoodsEntity> localList) {
        Intent intent = new Intent(activity, ACT_SearchStockInOrOut.class);
        Bundle bundle = new Bundle();
        bundle.putSerializable(KEY_SELECTED_REPO, selectedRepo);
        bundle.putSerializable(KEY_LOCAL_LIST, localList);
        bundle.putInt(KEY_STOCK_TYPE, FRA_StockOut.STOCK_TYPE_OUT);
        intent.putExtras(bundle);
        activity.startActivity(intent);
    }

    public static void startActFromStockIn(Activity activity, RepositoryEntity selectedRepo, LinkedList<RepoListGoodsEntity> localList, boolean isOtherStockIn) {
        Intent intent = new Intent(activity, ACT_SearchStockInOrOut.class);
        Bundle bundle = new Bundle();
        bundle.putSerializable(KEY_SELECTED_REPO, selectedRepo);
        bundle.putSerializable(KEY_LOCAL_LIST, localList);
        bundle.putInt(KEY_STOCK_TYPE, FRA_StockIn.STOCK_TYPE_IN);
        bundle.putBoolean(KEY_OTHER_IN_TYPE, isOtherStockIn);
        intent.putExtras(bundle);
        activity.startActivity(intent);
    }

    @Override
    public void showGoodsList(List<RepoListGoodsEntity> goodsEntities, boolean isRefresh) {

        refreshLayout.finishRefresh();
        rvCart.refreshComplete(AppConstants.PAGE_SIZE);
        if (ListUtil.isListEmpty(goodsEntities)) {
            rvCart.setNoMore(true);
        }

        updateListAccordingToLocalCart(goodsEntities);

        mStockAdapter.update(goodsEntities, isRefresh);
        if (isRefresh) {
            rvCart.setAdapter(mGoodsViewAdapter);
        } else {
            mGoodsViewAdapter.notifyDataSetChanged();
        }

        tvSelectCount.setText(String.valueOf(mStockAdapter.getSelectedCount()));
        tvConfirm.setEnabled(mStockAdapter.getSelectedCount() > 0);

        updateStockSearchResultUI(ListUtil.isListEmpty(mStockAdapter.getDataList()));

        if (ListUtil.isListEmpty(mStockAdapter.getDataList())) {
            toggleShowEmpty(true, R.mipmap.ic_bill_empty, "未搜索到商品", "");
        } else {
            toggleShowEmpty(false);
        }

    }

    private void updateListAccordingToLocalCart(List<RepoListGoodsEntity> requestedList) {

        List<RepoListGoodsEntity> targetList = null;
        if (!ListUtil.isListEmpty(mSelectedData)) {
            targetList = mSelectedData;
        }else if (!ListUtil.isListEmpty(localCartList)) {
            targetList = localCartList;
        }

        if (!ListUtil.isListEmpty(targetList)) {
            for (RepoListGoodsEntity requestedEntity : requestedList) {
                for (RepoListGoodsEntity localEntity : targetList) {
                    if (localEntity.getGoodsId().equals(requestedEntity.getGoodsId())) {
                        if (localEntity.getIsBatch() == RepoListGoodsEntity.BATCH_OFF) {
                            requestedEntity.setSelectedCount(localEntity.getSelectedCount());
                        } else {
                            // 多批次商品，匹配批次号，设置已选值
                            outer:
                            for (RepoGoodsEntity localBatch : localEntity.getGoodsBatch()) {
                                for (RepoGoodsEntity requestedBatch : requestedEntity.getGoodsBatch()) {
                                    if (requestedBatch.getGoodsBatchNumber().equals(localBatch.getGoodsBatchNumber())) {
                                        requestedBatch.setSelectedCount(localBatch.getSelectedCount());
                                        continue outer;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    protected void showNetErrorEmpty() {
        refreshLayout.finishRefresh();
        showNetErrorEmpty(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ACT_SearchStockInOrOut.super.toggleCloseEmpty();
                refreshLayout.autoRefresh();
            }
        });
    }

    @Override
    public void showError(String msg) {
        super.showError(msg);
        updateStockSearchResultUI(false);
        toggleShowEmpty(true, R.mipmap.ic_bill_empty, "未搜索到商品", "");
        refreshLayout.finishRefresh();
    }

}
